#include "all.h"

uint8_t num1,num2,num3,num4,num5,num6;
uint8_t  DataStorage[10];
/*应答机制*/
tTime   ACK_state;

tTime Time_NRF24L01_Register;//NRF24L01注册功能计时
uint8_t NRF24L01_OK=0;

u8 status = 0;		 //用于判断接收/发送状态
u8 txbuf[RX_PLOAD_WIDTH];	 //发送缓冲
u8 rxbuf[RX_PLOAD_WIDTH];	 //接收缓冲


u8 RX_BUF[RX_PLOAD_WIDTH];		//接收数据缓存
u8 TX_BUF[TX_PLOAD_WIDTH];		//发射数据缓存
//u8 TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};  // 定义一个静态发送地址
//u8 RX_ADDRESS[RX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; 

u8 TX_ADDRESS[TX_ADR_WIDTH] = {NRF_24L01_Add,NRF_24L01_Add,NRF_24L01_Add,Bed_Code,Bed_Class};  // 定义一个静态发送地址
u8 RX_ADDRESS[RX_ADR_WIDTH] = {NRF_24L01_Add,NRF_24L01_Add,NRF_24L01_Add,Bed_Code,Bed_Class}; 


/***********************************************************************************************************************************************************/
/*************************************************************************
	  NRF24L01驱动部分
**************************************************************************/

void Delay(__IO u32 nCount)
{
  for(; nCount != 0; nCount--);
} 

/**
  * @brief  SPI的 I/O配置
  * @param  无
  * @retval 无
  */
void SPI_NRF_Init(void)
{
  SPI_InitType  SPI_InitStructure;
  GPIO_InitType GPIO_InitStructure;
  
 /*开启相应IO端口的时钟*/
  RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOE
                         |NRF_IRQ_GPIO_CLK
                         |NRF_CSN_GPIO_CLK
                         |NRF_CE_GPIO_CLK,ENABLE);
  
  RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);    // 使能 AFIO 复用时钟
  
 // // 使能 SW 关闭 JTAG (PA15 是 JTAG 的调试接口，关闭 JTAG 后才能当普通IO口用)
 // GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);    

 /*使能SPI2时钟*/
  RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_SPI2, ENABLE);
  GPIO_ConfigPinRemap(GPIO_RMP2_SPI2,ENABLE);
   /*配置 SPI_NRF_SPI的 SCK,MISO,MOSI引脚，GPIOE^11,GPIOE^12,GPIOE^13 */
  GPIO_InitStructure.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能
  GPIO_InitPeripheral(GPIOE, &GPIO_InitStructure);  

  /*配置SPI_NRF_SPI的CE引脚,和SPI_NRF_SPI的 CSN 引脚*/
   GPIO_InitStructure.Pin = NRF_CSN_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitPeripheral(NRF_CSN_GPIO_PORT, &GPIO_InitStructure);
  
   GPIO_InitStructure.Pin = NRF_CE_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitPeripheral(NRF_CE_GPIO_PORT, &GPIO_InitStructure);
  

   /*配置SPI_NRF_SPI的IRQ引脚*/
  GPIO_InitStructure.Pin = NRF_IRQ_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;  //上拉输入
  GPIO_InitPeripheral(NRF_IRQ_GPIO_PORT, &GPIO_InitStructure); 
		  
  /* 这是自定义的宏，用于拉高csn引脚，NRF进入空闲状态 */
  NRF_CSN_HIGH(); 
 
  SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX; //双线全双工
  SPI_InitStructure.SpiMode = SPI_MODE_MASTER;	 					//主模式
  SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;	 				//数据大小8位
  SPI_InitStructure.CLKPOL = SPI_CLKPOL_LOW;		 				//时钟极性，空闲时为低
  SPI_InitStructure.CLKPHA = SPI_CLKPHA_FIRST_EDGE;						//第1个边沿有效，上升沿为采样时刻
  SPI_InitStructure.NSS = SPI_NSS_SOFT;		   					//NSS信号由软件产生
  SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_8;  //8分频，9MHz
  SPI_InitStructure.FirstBit = SPI_FB_MSB;  				//高位在前
  SPI_InitStructure.CRCPoly = 7;
  SPI_Init(SPI2, &SPI_InitStructure);

  /* Enable SPI2  */
  SPI_Enable(SPI2, ENABLE);
}

/**
  * @brief   用于向NRF读/写一字节数据
  * @param   写入的数据
  *		@arg dat 
  * @retval  读取得的数据
  */
u8 SPI_NRF_RW(u8 dat)
{  	
   /* 当 SPI发送缓冲器非空时等待 */
  while (SPI_I2S_GetStatus(SPI2, SPI_I2S_TE_FLAG) == RESET);
  
   /* 通过 SPI2发送一字节数据 */
  SPI_I2S_TransmitData(SPI2, dat);		
 
   /* 当SPI接收缓冲器为空时等待 */
  while (SPI_I2S_GetStatus(SPI2, SPI_I2S_RNE_FLAG) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI2);
}

/**
  * @brief   用于向NRF特定的寄存器写入数据
  * @param   
  *		@arg reg:NRF的命令+寄存器地址
  *		@arg dat:将要向寄存器写入的数据
  * @retval  NRF的status寄存器的状态
  */
u8 SPI_NRF_WriteReg(u8 reg,u8 dat)
{
 	u8 status;
	 NRF_CE_LOW();
	/*置低CSN，使能SPI传输*/
    NRF_CSN_LOW();
				
	/*发送命令及寄存器号 */
	status = SPI_NRF_RW(reg);
		 
	 /*向寄存器写入数据*/
    SPI_NRF_RW(dat); 
	          
	/*CSN拉高，完成*/	   
  	NRF_CSN_HIGH();	
		
	/*返回状态寄存器的值*/
   	return(status);
}

/**
  * @brief   用于从NRF特定的寄存器读出数据
  * @param   
  *		@arg reg:NRF的命令+寄存器地址
  * @retval  寄存器中的数据
  */
u8 SPI_NRF_ReadReg(u8 reg)
{
 	u8 reg_val;

	NRF_CE_LOW();
	/*置低CSN，使能SPI传输*/
 	NRF_CSN_LOW();
				
  	 /*发送寄存器号*/
	SPI_NRF_RW(reg); 

	 /*读取寄存器的值 */
	reg_val = SPI_NRF_RW(NOP);
	            
   	/*CSN拉高，完成*/
	NRF_CSN_HIGH();		
   	
	return reg_val;
}	

/**
  * @brief   用于向NRF的寄存器中写入一串数据
  * @param   
  *		@arg reg : NRF的命令+寄存器地址
  *		@arg pBuf：用于存储将被读出的寄存器数据的数组，外部定义
  * 	@arg bytes: pBuf的数据长度
  * @retval  NRF的status寄存器的状态
  */
u8 SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes)
{
 	u8 status, byte_cnt;

	  NRF_CE_LOW();
	/*置低CSN，使能SPI传输*/
	NRF_CSN_LOW();
		
	/*发送寄存器号*/		
	status = SPI_NRF_RW(reg); 

 	/*读取缓冲区数据*/
	 for(byte_cnt=0;byte_cnt<bytes;byte_cnt++)		  
	   pBuf[byte_cnt] = SPI_NRF_RW(NOP); //从NRF24L01读取数据  

	 /*CSN拉高，完成*/
	NRF_CSN_HIGH();	
		
 	return status;		//返回寄存器状态值
}

/**
  * @brief   用于向NRF的寄存器中写入一串数据
  * @param   
  *		@arg reg : NRF的命令+寄存器地址
  *		@arg pBuf：存储了将要写入写寄存器数据的数组，外部定义
  * 	@arg bytes: pBuf的数据长度
  * @retval  NRF的status寄存器的状态
  */
u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)
{
	 u8 status,byte_cnt;
	 NRF_CE_LOW();
   	 /*置低CSN，使能SPI传输*/
	 NRF_CSN_LOW();			

	 /*发送寄存器号*/	
  	 status = SPI_NRF_RW(reg); 
 	
  	  /*向缓冲区写入数据*/
	 for(byte_cnt=0;byte_cnt<bytes;byte_cnt++)
		SPI_NRF_RW(*pBuf++);	//写数据到缓冲区 	 
	  	   
	/*CSN拉高，完成*/
	NRF_CSN_HIGH();			
  
  	return (status);	//返回NRF24L01的状态 		
}

/**
  * @brief  配置并进入接收模式
  * @param  无
  * @retval 无
  */
void NRF_RX_Mode(void)

{
	NRF_CE_LOW();	

   SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址

   SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01);    //使能通道0的自动应答    

   SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址    

   SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL);      //设置RF通信频率    

   SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度      

   SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x07); //设置TX发射参数,-12db增益,1Mbps,低噪声增益开启    

   SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f);  //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 

/*CE拉高，进入接收模式*/	
  NRF_CE_HIGH();

}    

/**
  * @brief  配置发送模式
  * @param  无
  * @retval 无
  */
void NRF_TX_Mode(void)
{  
	NRF_CE_LOW();		

   SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);    //写TX节点地址 

   SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK   

   SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答    

   SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址  

   SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次

   SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL);       //设置RF通道为CHANAL

   SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x07); //设置TX发射参数,-12db增益,1Mbps,低噪声增益开启     
	
   SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断

/*CE拉高，进入发送模式*/	
  NRF_CE_HIGH();
    Delay(0xffff); //CE要拉高一段时间才进入发送模式
}

/**
  * @brief  配置掉电模式
  * @param  无
  * @retval 无
  */
void NRF_PowerDown_Mode(void)
{
	NRF_CE_LOW();		
	
   SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x00);    //配置基本工作模式  掉电模式

/*CE拉高，进入发送模式*/	
  NRF_CE_HIGH();
  Delay(0xffff); //CE要拉高一段时间才进入发送模式
}	
/**
  * @brief  主要用于NRF与MCU是否正常连接
  * @param  无
  * @retval SUCCESS/ERROR 连接正常/连接失败
  */
u8 NRF_Check(void)
{
	u8 buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2};
	u8 buf1[5];
	u8 i; 
	 
	/*写入5个字节的地址.  */  
	SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,buf,5);

	/*读出写入的地址 */
	SPI_NRF_ReadBuf(TX_ADDR,buf1,5); 
	 
	/*比较*/               
	for(i=0;i<5;i++)
	{
		if(buf1[i]!=0xC2)
		break;
	} 
	       
	if(i==5)
		return SUCCESS ;        //MCU与NRF成功连接 
	else
		return ERROR ;        //MCU与NRF不正常连接
}

/**
  * @brief   用于向NRF的发送缓冲区中写入数据
  * @param   
  *		@arg txBuf：存储了将要发送的数据的数组，外部定义	
  * @retval  发送结果，成功返回TXDS,失败返回MAXRT或ERROR
  */
u8 NRF_Tx_Dat(u8 *txbuf)
{
	u8 state;  

	 /*ce为低，进入待机模式1*/
	NRF_CE_LOW();

	/*写数据到TX BUF 最大 32个字节*/						
   SPI_NRF_WriteBuf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);

      /*CE为高，txbuf非空，发送数据包 */   
 	 NRF_CE_HIGH();
	  	
	  /*等待发送完成中断 */                            
	while(NRF_Read_IRQ()!=0); 	
	
	/*读取状态寄存器的值 */                              
	state = SPI_NRF_ReadReg(STATUS);

	 /*清除TX_DS或MAX_RT中断标志*/                  
	SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state); 	

	SPI_NRF_WriteReg(FLUSH_TX,NOP);    //清除TX FIFO寄存器 

	 /*判断中断类型*/    
	if(state&MAX_RT)                     //达到最大重发次数
			 return MAX_RT; 

	else if(state&TX_DS)                  //发送完成
		 	return TX_DS;
	 else						  
			return ERROR;                 //其他原因发送失败
} 

/**
  * @brief   用于从NRF的接收缓冲区中读出数据
  * @param   
  *		@arg rxBuf ：用于接收该数据的数组，外部定义	
  * @retval 
  *		@arg 接收结果
  */
u8 NRF_Rx_Dat(u8 *rxbuf)
{
	u8 state; 
	NRF_CE_HIGH();	 //进入接收状态
	 /*等待接收中断*/
	while(NRF_Read_IRQ()==0)
  {
    NRF_CE_LOW();  	 //进入待机状态
    /*读取status寄存器的值  */               
    state=SPI_NRF_ReadReg(STATUS);
     
    /* 清除中断标志*/      
    SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);

    /*判断是否接收到数据*/
    if(state&RX_DR)                                 //接收到数据
    {
      SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
         SPI_NRF_WriteReg(FLUSH_RX,NOP);          //清除RX FIFO寄存器
      return RX_DR; 
    }
    else    
      return ERROR;                    //没收到任何数据
  }
  
  return ERROR;                    //没收到任何数据
}


/***********************************************************************************************************************************************************/




/*************************************************************************
	  NRF24L01  APP部分
**************************************************************************/



void NRF24L01_time(void)
{
   if(Time_NRF24L01_Register.Flag)Time_NRF24L01_Register.MS++;
}	
void NRF24L01_Handle(void)
{
		if(NRF24L01_OK==1)NRF24L01_RX();  //判断器件存在以后才能接收数据
		ACK_Task();
}	

//接收函数
void NRF24L01_RX(void)
{
	  uint8_t temp[RX_PLOAD_WIDTH];
	  uint8_t i=0,aXOR = 0; 
    /* 等待接收数据 */
    status = NRF_Rx_Dat(rxbuf);

    /* 判断接收状态 */
    if(status == RX_DR)
    {
			  memcpy(temp,rxbuf,RX_PLOAD_WIDTH);
				/*XOR*/
				for(i = 0;i < temp[2];i++)
				{
					aXOR ^= temp[i+2];		
				}	 
				if(temp[29]==aXOR)
				{
					 if(temp[3]==Bed_Code&&temp[4]==Bed_Class&&temp[5]==0xAA)  //判断类别与床垫码是否一样
					 {
						 if(temp[6]==Bed_info.ID[0]&&temp[7]==Bed_info.ID[1]&&temp[8]==Bed_info.ID[2]&&temp[9]==Bed_info.ID[3]&&temp[10]==Bed_info.ID[4]&&temp[11]==Bed_info.ID[5]&&temp[12]==Bed_info.ID[6])
						 {
							 ACK_Dis();/*应答机制关闭*/
							 if(temp[13]==0x88&&temp[14]==0x88&&temp[15]==0x88&&temp[16]==0x88&&temp[17]==0x88&&temp[18]==0x88&&temp[19]==0x88)
							 {	 
								 Chinese_Show_one(30,40,0,32,0);
								 Bed_info.Wifi = 0x01;
								 //Time_Heart.Num = 1;  
								 Write_Flash_Buff(Bed_ADDR, 0, (uint8_t *)&Bed_info.head, sizeof(struct tBed_info));//写入遥控器ID FLASH 
								 memset(rxbuf, 0, sizeof(rxbuf));	  //清零等待下次数据
							 }
							 else
							 if(temp[13]==0x99&&temp[14]==0x99&&temp[15]==0x99&&temp[16]==0x99&&temp[17]==0x99&&temp[18]==0x99&&temp[19]==0x99)
							 {	 
								 LCD_Fill(30,40,30+32,40+32,0x0000);
								 Bed_info.Wifi = 0x00;
								 Write_Flash_Buff(Bed_ADDR, 0, (uint8_t *)&Bed_info.head, sizeof(struct tBed_info));//写入遥控器ID FLASH 
								 memset(rxbuf, 0, sizeof(rxbuf));	  //清零等待下次数据
							 }
						 }  	
					 }		
			  }			 
			  memset(rxbuf, 0, sizeof(rxbuf));	  //清零等待下次数据
    }	
}	
void NRF24L01_Fun(uint8_t fun1,uint8_t fun2,uint8_t fun3,uint8_t fun4,uint8_t fun5,uint8_t fun6)
{

}	



/*
 NRF24L01 变量初始化
*/
void NRF24L01_Variable_Init(void)
{
		/*检测NRF模块与MCU的连接*/		
		if(NRF_Check() == SUCCESS)	  //连接成功
		{
				NRF24L01_OK=1;
		}		
		else
		{
				NRF24L01_OK=0;
		}	
	    NRF_RX_Mode();                // NRF 进入接收模式
}	

void NRF24L01_TX(uint8_t *data,uint8_t size)
{
		uint8_t i=0,aXOR = 0,k=0; 
		memset(txbuf, 0, sizeof(txbuf));	  //清零等待下次数据
		/*包头*/
		txbuf[0]=0x55;
		txbuf[1]=0x66;	
		/*有效字节*/
		txbuf[2]=27;
		/*床垫码*/
		txbuf[3]=Bed_Code;	
		/*类别码*/
		txbuf[4]=Bed_Class;	
		/*命令码*/
		txbuf[5]=Bed_TX;	
		/*ID*/
		txbuf[6]=Bed_info.ID[0];
		txbuf[7]=Bed_info.ID[1];
		txbuf[8]=Bed_info.ID[2];
		txbuf[9]=Bed_info.ID[3];
		txbuf[10]=Bed_info.ID[4];
		txbuf[11]=Bed_info.ID[5];
		txbuf[12]=Bed_info.ID[6];			
		/*数据段*/
		for(k=0;k<size;k++)
		{
			txbuf[13+k]=data[k];
		}	
		/*XOR*/	
		for(i = 0;i < txbuf[2];i++)
		{
			aXOR ^= txbuf[i+2];		
		}	  			
		txbuf[29]=aXOR;			
		/*包尾*/		
		txbuf[30]=0xAA;
		txbuf[31]=0xBB;			
		/* 发送数据 */
		NRF_TX_Mode();

		status = NRF_Tx_Dat(txbuf);

		/* 发送数据的状态 */
		if(status == TX_DS)
		{
		}
		else
		{
		}
		/* 接收数据 */
		NRF_RX_Mode();	
		//ACK_En();/*应答机制开启*/	
}	
/*应答开启*/
void ACK_En(void)
{
	ACK_state.Num = 1;
}
/*应答关闭*/
void ACK_Dis(void)
{
	ACK_state.Num = 0;
}
/*应答任务*/
void ACK_Task(void)
{
	switch(ACK_state.Num)
	{
		case 0: break;
		case 1: 
			ACK_state.MS = 300;
			ACK_state.Num += 1;
			break;
		case 2: 
			if(ACK_state.MS<=0)ACK_state.Num += 1;
			break;
		case 3: 
			/* 发送数据 */
			NRF_TX_Mode();
			status = NRF_Tx_Dat(txbuf);
			/* 发送数据的状态 */
			if(status == TX_DS)
			{
			}
			else
			{
			}
			/* 接收数据 */
			NRF_RX_Mode();	
			ACK_state.Num = 0;
			break;		
	
	}	
}


/*7位数据发送*/
void NRF_Data_Storage7(uint8_t CMD1,uint8_t CMD2,uint8_t CMD3,uint8_t CMD4,uint8_t CMD5,uint8_t CMD6,uint8_t CMD7)
{
	memset(DataStorage, 0, sizeof(DataStorage));	  //清零等待下次数据
	DataStorage[0]=CMD1;
	DataStorage[1]=CMD2;
	DataStorage[2]=CMD3;
	DataStorage[3]=CMD4;
	DataStorage[4]=CMD5;
	DataStorage[5]=CMD6;
	DataStorage[6]=CMD7;	
	NRF24L01_TX(DataStorage,7);	
}	
/*8位数据发送*/
void NRF_Data_Storage8(uint8_t CMD1,uint8_t CMD2,uint8_t CMD3,uint8_t CMD4,uint8_t CMD5,uint8_t CMD6,uint8_t CMD7,uint8_t CMD8)
{
	memset(DataStorage, 0, sizeof(DataStorage));	  //清零等待下次数据
	DataStorage[0]=CMD1;
	DataStorage[1]=CMD2;
	DataStorage[2]=CMD3;
	DataStorage[3]=CMD4;
	DataStorage[4]=CMD5;
	DataStorage[5]=CMD6;
	DataStorage[6]=CMD7;	
	DataStorage[7]=CMD8;		
	NRF24L01_TX(DataStorage,8);	
}


/*********************************************END OF FILE**********************/




	




